package com.mobile.framework.tag;


import com.mobile.framework.util.Constants;
import com.mobile.framework.util.PageList;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts.taglib.TagUtils;
import org.apache.struts.taglib.html.BaseTag;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.jsp.JspException;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

/**
 * Standard page navigator. usage: <app:page name="users"
 * searchForm="searchUserForm" showJumpBox="false" showRowSelect="true"
 * rowNumber="5,10,30">
 * name设置数据集(必须是PageList)的名称,searchForm设置相关查询表单的名称,如果设置该属性将自动生成相关javascript代码
 * showJumpBox 决定是否显示页面跳转框,showRowSelect决定是否显示每页记录数选择框,rowNumber决定可选的每页记录数
 * 除name属性,其他都是可选属性,缺省控制由config.property文件中page.jump.disable,page.rows配置决定
 */
public class PageAjaxTag extends BaseTag {

    private static String LABEL_FIRST_PAGE = "第一页";

    private static String LABEL_PREVIOUS_PAGE = "上一页";

    private static String LABEL_NEXT_PAGE = "下一页";

    private static String LABEL_LAST_PAGE = "最后一页";

    private static String LABEL_GO_PAGE = "跳转";

    private static String LABEL_ROWS_PER_PAGE = "每页记录数";

    private static String[] LABEL_PAGE_SUMMARY = {"第{", "}/{", "}页 共{", "}条记录"};

    private static String ERROR_PAGE_NUMBER = "输入的页码无效";

    private static String COMMON_BUNDLE_KEY = "common";

    private Log log = LogFactory.getLog(this.getClass());

    private static StringBuffer templateJavaScript = null;

    private String content = "";

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    // ----------------------------------------------------- Instance Variables

    /**
     * Bean name of the recordset, you need to set this value in your action
     * class and give this value in your jsp file
     */
    private String space = " ";

    public String getFun() {
        return fun;
    }

    public void setFun(String fun) {
        this.fun = fun;
    }

    private String fun = "";

    protected String name;// 数据集对象名

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    protected String searchForm = null;// 搜索表单名

    public String getSearchForm() {
        return searchForm;
    }

    public void setSearchForm(String searchForm) {
        this.searchForm = searchForm;
    }

    protected String showJumpBox = null;// 是否显示跳转框

    public String getShowJumpBox() {
        return showJumpBox;
    }

    public void setShowJumpBox(String showJumpBox) {
        this.showJumpBox = showJumpBox;
    }

    protected String showRowSelect = "false";// 是否显示每页数选择框

    public String getShowRowSelect() {
        return showRowSelect;
    }

    public void setShowRowSelect(String showRowSelect) {
        this.showRowSelect = showRowSelect;
    }

    protected String rowNumber = null;// 可选的每页记录数

    public String getRowNumber() {
        return rowNumber;
    }

    public void setRowNumber(String rowNum) {
        this.rowNumber = rowNum;
    }

    /**
     * Process the start of this tag. Overwirte super class's method. Do nothing
     * instead of render base element.
     *
     * @throws javax.servlet.jsp.JspException if a JSP exception has occurred
     */
    @Override
    public int doStartTag() throws JspException {
        return EVAL_BODY_INCLUDE;
    }

    /**
     * Render an input element for this tag.
     *
     * @throws javax.servlet.jsp.JspException if a JSP exception has occurred
     */
    @Override
    public int doEndTag() throws JspException {

        // Create an appropriate "input" element based on our parameters
        StringBuffer results = new StringBuffer();
        Object bean = TagUtils.getInstance().lookup(pageContext, name, null);
        if (name != null && bean == null) {
            // throw new JspException(messages.getMessage("getter.bean", name));
            bean = new PageList();
        }

        // 是否显示分页跳转和记录数选择框(缺省值)
        boolean showJumpSelect = "true".equals("false") ? false : true;

        try {
            PageList p = (PageList) bean;

            // 表单头
            // 加onSubmit避免提交当前表单
            results.append("<table class='STYLEPage' ><tr><td style='font-size:12px;text-align:center;'>");
            // 最大页数
            results.append("<input type=\"hidden\" name=\"maxPage\" value=\"")
                    .append(p.getPageCount()).append("\">");

            showPageInfo(results, p);
            if ((null == showJumpBox && showJumpSelect)
                    || "true".equals(showJumpBox)) {
                showJumpBox(results);
            }
            if ((null == showRowSelect && showJumpSelect)
                    || "true".equals(showRowSelect)) {
                showRowSelect(results);
            }

            // 表单尾
            results.append("</td></tr></table>");
            if (null != searchForm && !"".equals(searchForm)) {
                showJavaScript(results, searchForm, p.getPageCount());
            }

        } catch (Exception e) {
            log.error("doEndTag() error:" + e, e);
            throw new JspException(e.getMessage(), e);
        }

        // Render this element to our response
        TagUtils.getInstance().write(pageContext, results.toString());

        // Continue evaluating this page
        return (EVAL_PAGE);

    }

    // 显示分页信息和链接

    private void showPageInfo(StringBuffer results, PageList p)
            throws JspException {

        int currentPage = p.getCurrentPage();
        int pageCount = p.getPageCount();
        int totalRowCount = p.getTotalRowCount();

        // 合计页数
        Object[] args = new Object[3];
        args[0] = new Integer(currentPage);
        args[1] = new Integer(pageCount);
        args[2] = new Integer(totalRowCount);
        results.append(getMessage(LABEL_PAGE_SUMMARY, args));
        results.append(space);

        // 第一页
        if (pageCount > 1 && currentPage > 1) {
            results.append("<a href=\"javascript:goPage(1)\">");
            results.append(getMessage(LABEL_FIRST_PAGE));
            results.append("</a>");
        } else {
            results.append(getMessage(LABEL_FIRST_PAGE));
        }
        results.append(space);

        // 上一页
        if (currentPage > 1) {
            results.append("<a href=\"javascript:goPage(" + (currentPage - 1)
                    + ")\">");
            results.append(getMessage(LABEL_PREVIOUS_PAGE));
            results.append("</a>");
        } else {
            results.append(getMessage(LABEL_PREVIOUS_PAGE));
        }
        results.append(space);

        // 下一页
        if (currentPage < pageCount) {
            results.append("<a href=\"javascript:goPage(" + (currentPage + 1)
                    + ")\">");
            results.append(getMessage(LABEL_NEXT_PAGE));
            results.append("</a>");
        } else {
            results.append(getMessage(LABEL_NEXT_PAGE));
        }
        results.append(space);

        // 最后一页
        if (currentPage < pageCount) {
            results.append("<a href=\"javascript:goPage(" + pageCount + ")\">");
            results.append(getMessage(LABEL_LAST_PAGE));
            results.append("</a>");
        } else {
            results.append(getMessage(LABEL_LAST_PAGE));
        }
        results.append(space);
    }

    // 显示跳转框

    private void showJumpBox(StringBuffer results) throws JspException {
        // 跳转页码输入框
        results.append(getMessage(LABEL_GO_PAGE));
        results.append("<input type=\"text\" name=\"page\" size=\"2\"").append(
                " class=\"input\">");
        results.append("<input type=\"button\" name=\"go\" class=\"button_bj\" ");
        results
                .append("   value=\"GO\" onclick=\"javascript:goPage(form.page.value)\"> ");
        results.append(space);

    }

    // 显示每页记录数选择框

    private void showRowSelect(StringBuffer results) throws JspException {
        // 每页记录数选择框
        results.append(getMessage(LABEL_ROWS_PER_PAGE));
        results.append(
                "<select onChange=\"javascript:setRowsPerPage(this.value)\"")
                .append(" class=\"input\">");
        // 从request中取当前记录数
        HttpServletRequest req = (HttpServletRequest) pageContext.getRequest();
        String curRows = req.getParameter("rowsPerPage");
        if (null == curRows || "".equals(curRows)) {
            HttpSession ses = req.getSession();
            if (null != ses) {
                curRows = (String) ses.getAttribute("rowsPerPage");
            }
            if (null == curRows || "".equals(curRows)) {
                curRows = Constants.ROWS_PER_PAGE;
            }
        }
        // 可选每页记录数的值
        String rowsValueList = this.rowNumber;
        if (null == rowsValueList || "".equals(rowsValueList)) {
            // 从配置文件取可选记录数
            rowsValueList = "10,15,20,30,60,100";
        }
        StringTokenizer st = new StringTokenizer(rowsValueList, ",");
        boolean isSelected = false;
        // 生成下拉框
        while (st.hasMoreTokens()) {
            String row = st.nextToken();
            results.append("<option value=\"" + row + "\"");
            if (row.equals(curRows)) {
                results.append(" selected ");
                isSelected = true;
            }
            results.append(">" + row + "</option>");
        }
        if (isSelected == false) {
            results.append("<option value=\"" + curRows + "\"");
            results.append(" selected ");
            results.append(">" + curRows + "</option>");
        }
        results.append("</select>");
        results.append(space);
    }

    // 显示javascript

    private void showJavaScript(StringBuffer results, String formName,
                                int maxRows) throws JspException, IOException {
       
        if (templateJavaScript == null || templateJavaScript.length() == 0) {
            templateJavaScript = new StringBuffer();
            String s = "/PageAjaxTag.js";
            InputStream in = PageAjaxTag.class.getResourceAsStream(s);

            BufferedReader br = new BufferedReader(new InputStreamReader(in, "UTF-8"));
            //StringBuffer sb = new StringBuffer();
            String temp = "";
            while ((temp = br.readLine()) != null) {
                templateJavaScript.append("\n" + temp);
            }
        }
//        System.out.println(templateJavaScript);
        results.append(templateJavaScript.toString()
                .replaceAll("###searchForm###", searchForm)
                .replaceAll("###content###", this.getContent())
                .replaceAll("###fun###", this.getFun())
                .replaceAll("###ERROR_PAGE_NUMBER###", getMessage(ERROR_PAGE_NUMBER))
                .replaceAll("###maxRows###", String.valueOf(maxRows)));
    }

    private String getMessage(String key) throws JspException {
        // return TagUtils.getInstance().message(pageContext, null,
        // null, key);
        return key;
    }

    /**
     * @param key  key 资源名数组
     * @param args args 参数值数组
     * @throws javax.servlet.jsp.JspException if a JSP exception has occurred
     */
    private String getMessage(String[] key, Object[] args) throws JspException {
        StringBuffer value = new StringBuffer();
        int length = 0;
        Object[] max = null;
        if (key.length <= args.length) {
            length = key.length;
            max = args;
        } else {
            length = args.length;
            max = key;
        }
        for (int i = 0; i < length; i++) {
            value.append(key[i]).append(args[i]);
        }
        for (int j = length; j < max.length; j++) {
            value.append(max[j]);
        }
        return value.toString();
    }

}